Skip to content

fix: replace busy-wait loop in BallThread with wait/notify (#2977) - #3614

Open
KANISHKMAKKAR wants to merge 7 commits into
iluwatar:masterfrom
KANISHKMAKKAR:fix-2977-ballthread-busy-wait
Open

KANISHKMAKKAR wants to merge 7 commits into
iluwatar:masterfrom
KANISHKMAKKAR:fix-2977-ballthread-busy-wait

Conversation

@KANISHKMAKKAR

Copy link
Copy Markdown

Addresses item 2 (Twin / BallThread.java) of #2977.

Problem

While suspended, BallThread wakes every 250 ms only to re-check isSuspended and do nothing. Because resumeMe() merely flips the flag, it has no way to wake the sleeping thread, so resuming is delayed until the current sleep tick expires.

stopMe() has the same weakness.

Change

isSuspended is now guarded by a private lock. The run loop waits on that lock while suspended, and resumeMe() / stopMe() call notifyAll(). Polling is replaced by blocking, and resume takes effect immediately.

The Thread.sleep(250) animation pacing is intentional and left unchanged.

Result

Latency from resumeMe() to the first draw(), averaged over 5 runs:

resume latency
before 173 ms
after 1 ms

Notes

  • No test changes. BallThreadTest (suspend / resume / interrupt) passes unmodified, including the verifyNoMoreInteractions assertions and the RuntimeException-on-interrupt check.
  • notifyAll() in stopMe() is required: without it, stopping an already-suspended thread would block forever in wait().
  • twin/README.md embeds this class verbatim, so it is updated to match.
  • I did not claim a CPU reduction here. This loop sleeps rather than spinning, and measured CPU time was effectively zero both before and after. The real defect is responsiveness.
  • The other locations listed in Fix busy-waiting loops #2977 are untouched. The Retry classes use deliberate backoff sleeps rather than busy-waiting.

@github-actions

github-actions Bot commented Sep 29, 2026 •

Copy link
Copy Markdown

PR Summary

Replaced the busy-wait loop in BallThread with a wait/notify mechanism guarded by a private lock. BallThread now blocks while suspended and wakes immediately on resumeMe() or stopMe() via notifyAll(). Keeps the 250ms animation pacing. README updated to reflect the change. Tests unchanged.

Changes

File Summary
twin/src/main/java/com/iluwatar/twin/BallThread.java Introduced a private lock and replaced polling with a wait loop. suspendMe/resumeMe/stopMe now synchronize on the lock and use notifyAll, allowing immediate resume and proper stop behavior. Preserves 250ms draw/move cadence.
twin/README.md Updated README to document the BallThread wait/notify fix and new synchronization, reflecting the changed behavior and preserved animation cadence.

autogenerated by presubmit.ai

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM!

Review Summary

Commits Considered (2)
  • 7c10fec: docs: update twin README to match BallThread fix
  • 70d5788: fix: replace busy-wait in BallThread with wait/notify (#2977)
Files Processed (2)
  • twin/README.md (1 hunk)
  • twin/src/main/java/com/iluwatar/twin/BallThread.java (2 hunks)
Actionable Comments (0)
Skipped Comments (6)
  • twin/src/main/java/com/iluwatar/twin/BallThread.java [39-39]

    best_practice: "Introduce a dedicated synchronization lock for suspend/resume"

  • twin/src/main/java/com/iluwatar/twin/BallThread.java [50-55]

    best_practice: "Guard suspend state with wait loop"

  • twin/src/main/java/com/iluwatar/twin/BallThread.java [68-70]

    best_practice: "Synchronize suspendMe state update"

  • twin/src/main/java/com/iluwatar/twin/BallThread.java [75-78]

    best_practice: "Wake up thread on resume"

  • twin/src/main/java/com/iluwatar/twin/BallThread.java [83-87]

    enhancement: "Ensure stop notifies waiting thread"

  • twin/README.md [91-93]

    best_practice: "README aligns with implementation"

@codecov

codecov Bot commented Sep 29, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 84.08%. Comparing base (4cabb20) to head (07e2e3c).

Additional details and impacted files
@@             Coverage Diff              @@
##             master    #3614      +/-   ##
============================================
+ Coverage     84.06%   84.08%   +0.01%     
- Complexity     4353     4355       +2     
============================================
  Files          1133     1133              
  Lines         15400    15413      +13     
  Branches        739      740       +1     
============================================
+ Hits          12946    12960      +14     
+ Misses         2158     2157       -1     
  Partials        296      296              

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM!

Review Summary

Commits Considered (1)
  • 61b12ed: Update BallThreadTest.java
Files Processed (2)
  • twin/README.md (1 hunk)
  • twin/src/test/java/com/iluwatar/twin/BallThreadTest.java (1 hunk)
Actionable Comments (0)
Skipped Comments (2)
  • twin/README.md [91-137]

    enhancement: "Introduce wait/notify synchronization for suspension in BallThread."

  • twin/src/test/java/com/iluwatar/twin/BallThreadTest.java [117-129]

    enhancement: "Test: stop while suspended does not interact with BallItem."

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM!

Review Summary

Commits Considered (1)
  • 8356b1e: Update BallThreadTest.java
Files Processed (1)
  • twin/src/test/java/com/iluwatar/twin/BallThreadTest.java (1 hunk)
Actionable Comments (0)
Skipped Comments (3)
  • twin/src/test/java/com/iluwatar/twin/BallThreadTest.java [135-137]

    best_practice: "Flaky wait-for-WAITING loop in test"

  • twin/src/test/java/com/iluwatar/twin/BallThreadTest.java [161-161]

    best_practice: "Deterministic synchronization before interrupt"

  • twin/src/test/java/com/iluwatar/twin/BallThreadTest.java [140-141]

    maintainability: "Assert termination state after join"

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM!

Review Summary

Commits Considered (1)
  • a6cc3ef: Update BallThreadTest.java
Files Processed (1)
  • twin/src/test/java/com/iluwatar/twin/BallThreadTest.java (1 hunk)
Actionable Comments (0)
Skipped Comments (2)
  • twin/src/test/java/com/iluwatar/twin/BallThreadTest.java [114-144]

    maintainability: "Avoid busy-waiting when waiting for thread state."

  • twin/src/test/java/com/iluwatar/twin/BallThreadTest.java [145-166]

    maintainability: "Interruption handling test robustness."

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM!

Review Summary

Commits Considered (1)
  • 568f395: Update BallThreadTest.java
Files Processed (1)
  • twin/src/test/java/com/iluwatar/twin/BallThreadTest.java (1 hunk)
Actionable Comments (0)
Skipped Comments (0)

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM!

Review Summary

Commits Considered (1)
  • 07e2e3c: Update BallThreadTest.java
Files Processed (0)
Actionable Comments (0)
Skipped Comments (0)

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant